<?php

namespace App\Lib\Rooms\Services;

use App\Lib\_Error\ExecuteException;
use App\Lib\_Error\ValidateException;
use App\Lib\LibBaseService;
use App\Ma\BaseData;
use App\Model\RoomsModel;
use App\Model\RoundsModel;

/**
 * 回合
 * Class RoundsService
 * @package App\Lib\Rooms\Services
 */
class RoundsService extends LibBaseService
{


    /**
     * 1、创建回合（开始游戏）
     * @param RoomsModel $room
     * @param array $ids
     * @return RoundsModel
     * @throws ValidateException
     * @throws ExecuteException
     */
    public function create(RoomsModel $room, array $ids): RoundsModel
    {
        if ($room->number - 1 > count($ids)) {
            throw new ValidateException('人数不足、暂无法开始');
        }
        array_push($ids, $room->owner);
        shuffle($ids);
        /** @var RoundsModel $rounds */
        $rounds = $room->Rounds()->create([
            'number' => $room->number,
            'has_zi_pai' => $room->has_zi_pai,
            'lai_zi' => $room->lai_zi,
            'banker_id' => $ids[0],
            'prev_id' => $ids[1] ?? 0,
            'next_id' => $ids[2] ?? 0,
            'opposite_id' => $ids[3] ?? 0,
        ]);
        if (!$rounds->save()) {
            throw new ExecuteException('创建回合失败');
        }
        return $rounds;
    }

    /**
     * 2、洗牌
     * @param RoundsModel $rounds
     * @return RoundsModel
     * @throws ExecuteException
     * @throws ValidateException
     */
    public function shuffleCards(RoundsModel $rounds)
    {
        if (!empty($rounds->remain_cards)) {
            throw new ValidateException('该回合已经洗过牌了');
        }
        $cards = BaseData::shuffleCards($rounds->has_zi_pai, $rounds->lai_zi);
        $rounds->remain_cards = $cards;
        if (!$rounds->save()) {
            throw new ExecuteException('洗牌失败');
        }
        return $rounds;
    }


    /**
     * 3、掷骰子
     * @param RoundsModel $rounds
     * @return RoundsModel
     * @throws ExecuteException
     * @throws ValidateException
     */
    public function touZi(RoundsModel $rounds)
    {
        if (!empty($rounds->shai_zi)) {
            throw new ValidateException('该回合已经掷过骰子了');
        }
        $touZi = [];
        for ($i = 0; $i < 3; $i++) {
            $touZi[] = mt_rand(1, 6);
        }
        $rounds->shai_zi = $touZi;
        if (!$rounds->save()) {
            throw new ExecuteException('掷骰子失败');
        }
        return $rounds;
    }

    /**
     * 4、发牌
     * @param RoundsModel $rounds
     * @return RoundsModel
     * @throws ExecuteException
     * @throws ValidateException
     */
    public function dealCards(RoundsModel $rounds)
    {
        $cards = $rounds->remain_cards;
        if (empty($cards)) { // 不应该出现该错误
            throw new ValidateException('该回合未洗牌');
        }
        if (!empty($rounds->banker_cards)) {
            throw new ValidateException('已经发过牌了');
        }
        $number = $rounds->number;
        for ($i = 0; $i < $number; $i++) {
            switch ($i) {
                case 0;
                    $rounds->banker_cards = array_splice($cards, -13);
                    break;
                case 1;
                    $rounds->prev_cards = array_splice($cards, -13);
                    break;
                case 2;
                    $rounds->next_cards = array_splice($cards, -13);
                    break;
                case 3;
                    $rounds->opposite_cards = array_splice($cards, -13);
                    break;
            }
        }
        $rounds->remain_cards = $cards;

        if (!$rounds->save()) {
            throw new ExecuteException('发牌失败');
        }
        // 庄家摸第一张牌
        $this->container->get(ActionService::class)->draw($rounds);
        $rounds->refresh(); // 重载模型
        return $rounds;
    }


    /**
     * 5、外围马（外围马数量和节节高待完善）
     * @param RoundsModel $rounds
     * @return RoundsModel
     * @throws ExecuteException
     * @throws ValidateException
     */
    public function dealMaCards(RoundsModel $rounds)
    {
        $cards = $rounds->remain_cards;
        if (empty($cards)) { // 不应该出现该错误
            throw new ValidateException('该回合未洗牌');
        }
        if (!empty($rounds->banker_ma)) {
            throw new ValidateException('已经拿过马了');
        }
        $number = $rounds->number;
        for ($i = 0; $i < $number; $i++) {
            switch ($i) {
                case 0;
                    $rounds->banker_ma = array_splice($cards, -2);
                    break;
                case 1;
                    $rounds->prev_ma = array_splice($cards, -2);
                    break;
                case 2;
                    $rounds->next_ma = array_splice($cards, -2);
                    break;
                case 3;
                    $rounds->opposite_ma = array_splice($cards, -2);
                    break;
            }
        }
        $rounds->remain_cards = $cards;

        if (!$rounds->save()) {
            throw new ExecuteException('拿码失败');
        }
        return $rounds;
    }
}